/*
 * Banshee.cpp
 *
 *  Created on: 28.07.2009
 *      Author: h3llfire
 */

#include "Banshee.h"
#include <glib.h>
#include <dbus/dbus-glib.h>
#include <string.h>
#include <stdio.h>


namespace Impp {



#define STRLEN 100

#define INTERVAL 15000
#define DBUS_TIMEOUT 100


gboolean dbus_g_running(DBusGConnection *connection, const char *name)
{
        DBusGProxy *dbus;
        GError *error = 0;
        gboolean running = FALSE;

        dbus = dbus_g_proxy_new_for_name(connection,
                        "org.freedesktop.DBus",
                        "/org/freedesktop/DBus",
                        "org.freedesktop.DBus");

        if (dbus)
          {
            if (dbus_g_proxy_call_with_timeout(dbus, "NameHasOwner", DBUS_TIMEOUT, &error,
                                               G_TYPE_STRING, name,
                                               G_TYPE_INVALID,
                                               G_TYPE_BOOLEAN, &running,
                                               G_TYPE_INVALID))
              {
                //printf("dbus name '%s' %s", name, running ? "has an owner" : "has no owner");
                return running;
              }
            else
              {
            	//printf("dbus NameHasOwner for %s failed %s", name, error->message);
                g_error_free(error);
              }
          }
        else
          {
        	printf("Failed to connect to Dbus");
          }

        return FALSE;
}

void banshee_hash_str(GHashTable *table, const char *key, char *dest)
{
        GValue* value = (GValue*) g_hash_table_lookup(table, key);
        if (value != NULL && G_VALUE_HOLDS_STRING(value)) {
                strncpy(dest, g_value_get_string(value), STRLEN-1);
        }
}

gboolean banshee_dbus_string(DBusGProxy *proxy, const char *method, char* dest)
{
        char *str = 0;
        GError *error = 0;
        if (!dbus_g_proxy_call_with_timeout (proxy, method, DBUS_TIMEOUT, &error,
                                G_TYPE_INVALID,
                                G_TYPE_STRING, &str,
                                G_TYPE_INVALID))
        {
                printf("Failed to make dbus call %s: %s", method, error->message);
                return FALSE;
        }

        strncpy(dest, str, STRLEN);
        dest[STRLEN-1] = 0;
        g_free(str);
        return TRUE;
}

int banshee_dbus_int(DBusGProxy *proxy, const char *method)
{
        int ret;
        GError *error = 0;
        if (!dbus_g_proxy_call_with_timeout (proxy, method, DBUS_TIMEOUT, &error,
                                G_TYPE_INVALID,
                                G_TYPE_INT, &ret,
                                G_TYPE_INVALID))
        {
        	printf("Failed to make dbus call %s: %s", method, error->message);
                return 0;
        }

        return ret;
}

unsigned int banshee_dbus_uint(DBusGProxy *proxy, const char *method)
{
        unsigned int ret;
        GError *error = 0;
        if (!dbus_g_proxy_call_with_timeout (proxy, method, DBUS_TIMEOUT, &error,
                                G_TYPE_INVALID,
                                G_TYPE_UINT, &ret,
                                G_TYPE_INVALID))
        {
        	printf("Failed to make dbus call %s: %s", method, error->message);
                return 0;
        }

        return ret;
}

void
get_banshee_info(TrackInfo* ti)
{
        DBusGConnection *connection;
        DBusGProxy *proxy;
        GError *error = 0;
        int status;
        char szStatus[STRLEN];

        connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
        if (connection == NULL) {
        	printf("Failed to open connection to dbus: %s\n", error->message);
                g_error_free (error);
                return;
        }

        if (dbus_g_running(connection, "org.bansheeproject.Banshee")) { // provide for new interface in banshee 1.0
                proxy = dbus_g_proxy_new_for_name (connection,
                                "org.bansheeproject.Banshee",
                                "/org/bansheeproject/Banshee/PlayerEngine",
                                "org.bansheeproject.Banshee.PlayerEngine");

                banshee_dbus_string(proxy, "GetCurrentState", szStatus);
                if (strcmp(szStatus, "idle") == 0) {
                        ti->status = PLAYER_STOPPED;
                        return;
                } else if (strcmp(szStatus, "playing") == 0)
                        ti->status = PLAYER_PLAYING;

                else
                        ti->status = PLAYER_PAUSED;

                GHashTable* table;
                if (!dbus_g_proxy_call_with_timeout (proxy, "GetCurrentTrack", DBUS_TIMEOUT, &error,
                                        G_TYPE_INVALID,
                                        dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &table,
                                        G_TYPE_INVALID))
                {
                        printf("Failed to make dbus call: %s", error->message);
                        return;
                }

                char album[256];
                char artist[256];
                char track[256];

                banshee_hash_str(table, "album", album);
                banshee_hash_str(table, "artist", artist);
                banshee_hash_str(table, "name", track);

                ti->album = wxString::FromUTF8(album);
                ti->artist = wxString::FromUTF8(artist);
                ti->track = wxString::FromUTF8(track);

                g_hash_table_destroy(table);

                ti->totalSecs = banshee_dbus_uint(proxy, "GetLength") / 1000;
                ti->currentSecs = banshee_dbus_uint(proxy, "GetPosition") / 1000;
                return;
        }

        ti->status = PLAYER_CLOSED;
}


Banshee::Banshee() {
	// TODO Auto-generated constructor stub

}

Banshee::~Banshee() {
	// TODO Auto-generated destructor stub
}

void Banshee::getInfo(TrackInfo* ti){
	get_banshee_info(ti);
}


}
